/*
 * 验证xml格式的正确性
 */
export function validateXML(xmlContent) {
  //errorCode 0是xml正确，1是xml错误，2是无法验证
  var xmlDoc,
    errorMessage,
    errorCode = 0;
  var errorLine = null;
  var errorColumn = null;
  var reason = null;
  // code for IE
  if (window.ActiveXObject) {
    xmlDoc = new ActiveXObject('Microsoft.XMLDOM');
    xmlDoc.async = 'false';
    xmlDoc.loadXML(xmlContent);

    if (xmlDoc.parseError.errorCode != 0) {
      errorMessage = '错误code: ' + xmlDoc.parseError.errorCode + '\n';
      errorMessage = errorMessage + '错误原因: ' + xmlDoc.parseError.reason;
      errorMessage = errorMessage + '错误位置: ' + xmlDoc.parseError.line;
      errorCode = 1;
      errorLine = xmlDoc.parseError.line;
      reason = xmlDoc.parseError.reason;
    } else {
      errorMessage = '格式正确';
    }
  }
  // code for Mozilla, Firefox, Opera, chrome, safari,etc.
  else if (document.implementation.createDocument) {
    var parser = new DOMParser();
    xmlDoc = parser.parseFromString(xmlContent, 'text/xml');
    var error = xmlDoc.getElementsByTagName('parsererror');
    if (error.length > 0) {
      if (xmlDoc.documentElement.nodeName == 'parsererror') {
        errorCode = 1;
        errorMessage = xmlDoc.documentElement.childNodes[0].nodeValue;
      } else {
        errorCode = 1;
        errorMessage = xmlDoc.getElementsByTagName('parsererror')[0].innerHTML;
      }
      const message = error[0].getElementsByTagName('div')[0].innerHTML;
      const line = errorMessage.match(/line (\S*) at/)[1];
      const column = errorMessage.match(/column (\S*):/)[1];
      reason = message.substring(message.indexOf(':') + 1);
      errorLine = parseInt(line);
      errorColumn = parseInt(column);
    } else {
      errorMessage = '格式正确';
    }
  } else {
    errorCode = 2;
    errorMessage = '浏览器不支持验证，无法验证xml正确性';
  }
  return {
    msg: errorMessage,
    error_code: errorCode,
    error_line: errorLine,
    error_column: errorColumn,
    reason,
  };
}

//格式化xml代码
export function formatXml(xmlStr) {
  let text = xmlStr;
  //使用replace去空格
  text =
    '\n' +
    text
      .replace(/(<\w+)(\s.*?>)/g, function($0, name, props) {
        return name + ' ' + props.replace(/\s+(\w+=)/g, ' $1');
      })
      .replace(/>\s*?</g, '>\n<');
  //处理注释
  text = text
    .replace(/\n/g, '\r')
    .replace(/<!--(.+?)-->/g, function($0, text) {
      var ret = '<!--' + escape(text) + '-->';
      return ret;
    })
    .replace(/\r/g, '\n');
  //调整格式  以压栈方式递归调整缩进
  var rgx = /\n(<(([^\?]).+?)(?:\s|\s*?>|\s*?(\/)>)(?:.*?(?:(?:(\/)>)|(?:<(\/)\2>)))?)/gm;
  var nodeStack = [];
  var output = text.replace(rgx, function(
    $0,
    all,
    name,
    isBegin,
    isCloseFull1,
    isCloseFull2,
    isFull1,
    isFull2,
  ) {
    var isClosed = isCloseFull1 == '/' || isCloseFull2 == '/' || isFull1 == '/' || isFull2 == '/';
    var prefix = '';
    if (isBegin == '!') {
      //!开头
      prefix = setPrefix(nodeStack.length);
    } else {
      if (isBegin != '/') {
        ///开头
        prefix = setPrefix(nodeStack.length);
        if (!isClosed) {
          //非关闭标签
          nodeStack.push(name);
        }
      } else {
        nodeStack.pop(); //弹栈
        prefix = setPrefix(nodeStack.length);
      }
    }
    var ret = '\n' + prefix + all;
    return ret;
  });
  var prefixSpace = -1;
  var outputText = output.substring(1);
  //还原注释内容
  outputText = outputText
    .replace(/\n/g, '\r')
    .replace(/(\s*)<!--(.+?)-->/g, function($0, prefix, text) {
      if (prefix.charAt(0) == '\r') prefix = prefix.substring(1);
      text = unescape(text).replace(/\r/g, '\n');
      var ret = '\n' + prefix + '<!--' + text.replace(/^\s*/gm, prefix) + '-->';
      return ret;
    });
  outputText = outputText.replace(/\s+$/g, '').replace(/\r/g, '\r\n');
  return outputText;
}

//计算头函数 用来缩进
function setPrefix(prefixIndex) {
  var result = '';
  var span = '    '; //缩进长度
  var output = [];
  for (var i = 0; i < prefixIndex; ++i) {
    output.push(span);
  }
  result = output.join('');
  return result;
}
